package org.springframework.security.access.vote;

import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author Dillon
 * @date 2024/7/30
 * @slogan 致敬大师 致敬未来的你
 * @desc 决策管理器实现之三
 */
@Deprecated
public class UnanimousBased extends AbstractAccessDecisionManager {

	public UnanimousBased(List<AccessDecisionVoter<?>> decisionVoters) {
		super(decisionVoters);
	}

	/**
	 * 权限决策，全部通过，才为通过
	 *
	 * @param authentication 认证主体
	 * @param object         请求访问包装
	 * @param attributes     当前请求所具有的权限
	 * @throws AccessDeniedException 执行异常
	 */
	@Override
	@SuppressWarnings({"rawtypes", "unchecked"})
	public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> attributes)
			throws AccessDeniedException {
		int grant = 0;
		List<ConfigAttribute> singleAttributeList = new ArrayList<>(1);
		singleAttributeList.add(null);
		for (ConfigAttribute attribute : attributes) {
			singleAttributeList.set(0, attribute);
			for (AccessDecisionVoter voter : getDecisionVoters()) {
				int result = voter.vote(authentication, object, singleAttributeList);
				switch (result) {
					case AccessDecisionVoter.ACCESS_GRANTED:
						grant++;
						break;
					case AccessDecisionVoter.ACCESS_DENIED:
						throw new AccessDeniedException(this.messages
								.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied"));
					default:
						break;
				}
			}
		}
		// To get this far, there were no deny votes
		if (grant > 0) {
			return;
		}
		// 兜底
		checkAllowIfAllAbstainDecisions();
	}

}
